package org.pojosoft.asfm.messaging
{
import org.pojosoft.asfm.Message;

/**
 * A messaging service based on the asynchronous Publish-Subscribe paradymn. In a publish/subscribe messaging
 * system, senders (publishers) publish messages onto one or more Topics. Receivers (subcribers) interested in
 * receiving messages sent to a particular topic must subscribe to that topic. Publishers are loosely coupled
 * from Subscribers, allowing for clean separation between UI code and data access code.
 *
 * This service can be used as a generic topic-based Publish-Subscribe implementation.
 *
 * But the more common usages of this service will be the request-response subscription model. The underlying
 * implementation of request-response makes use of a topic with a single publisher and a single subscriber.
 *
 * @author Duc Nguyen
 */
public interface IMessagingService
{
    /**
     * Publishes a message to the specified topic. Creates topic if it has not been created.
     *
     * @param topic The topic to publish the message
     * @param msg The message to publish
     */
    function publish(topic:String, msg:Message):void;

    /**
     * Registers a subscriber to the specified topic.
     *
     * @param topic
     * @param subscriber
     */
    function subscribe(topic:String, subscriber:IMessageHandler):void;

    /**
     * Removes a subscriber from the specified topic.
     *
     * @param topic
     * @param subscriber
     */
    function unsubscribe(topic:String, subscriber:IMessageHandler):void;

    /**
     * Submits a request and optionally specifies a handler for the result. For instance, a request is made
     * to retrieve an Employee from a backend db. There can be 2 outcomes to this request: 1) a successful
     * retrieval of the Employee record or 2) an error occurs during the retrieval and an exception is thrown.
     * Regardless of the outcome, the specified result handler must be able to handle both cases.
     *
     * Note that each request message has a type. Each request message type must be associated with a request
     * handler. Request handlers must be registered during application startup to handle all known message types.
     * An error will be thrown if a request handler is not found for a particular message type.
     *
     * @param msg The request message to be published to the underlying topic
     * @param resultHandler Handler responsible for handling the result of this request.
     * @see org.pojosoft.asfm.messaging.IMessagingService.setRequestHandler
     * @see org.pojosoft.asfm.messaging.IMessagingService.response
     */
    function request(msg:Message, resultHandler:IMessageHandler = null):void;

    /**
     * Submits a response for a previously submitted request. Note that the response message must contain
     * a correlationID in order for the service to correlate which response is for which service. The correlationID
     * is automatically generated by the messaging service implementation and is stored in the request message.
     *
     * @param msg The response message for a previously made request
     */
    function response(msg:Message):void;

    /**
     * Registers a request handler for a message type. Currently, only one request handler is allowed per
     * message type.
     *
     * @param msgType The mesage type
     * @param requestHandler The handler for the request message type
     */
    function setRequestHandler(msgType:String, requestHandler:IMessageHandler):void;

    /**
     * Retrieves the request handler for a message type
     * @param msgType The message type
     */
    function getRequestHandler(msgType:String):IMessageHandler;
}
}